#!/usr/bin/env python
# USP Terminal Plugin Version 1.0
##Description:VTE terminal window / cli
import gtk
import gtk.glade
import sys
import os
import gobject
import datetime
import gconf
import pango
import commands
import vte
import signal
from execute import *
from easygconf import *

global termPID
class pluginclass:
	TARGET_TYPE_TEXT = 80
	toButton = [ ( "text/uri-list", 0, TARGET_TYPE_TEXT ) ]
	"""This is the main class for the plugin"""
	"""It MUST be named pluginclass"""

	def __init__(self, USPWin):

		global termPID
		self.USPWin = USPWin

		#The Glade file for the plugin
		self.gladefile = os.path.join(os.path.dirname(__file__), "terminal.glade")

		#Read GLADE file
		self.wTree = gtk.glade.XML(self.gladefile,"window1")

		#These properties are NECESSARY to maintain consistency
		#throughout USP

		#Set 'window' property for the plugin (Must be the root widget)
		self.window = self.wTree.get_widget("window1")

		#Set 'heading' property for plugin
		self.heading = "Terminal"

		#This should be the first item added to the window in glade
		self.content_holder = self.wTree.get_widget("eventbox1")

		#Specify plugin width
		self.width = 150

		self.icon = 'gnome-terminal'

		self.gconf_dir = '/apps/usp/plugins/terminal'
		self.client = gconf.client_get_default()
		self.client.add_dir('/apps/usp/plugins/terminal', gconf.CLIENT_PRELOAD_NONE)
		self.client.notify_add('/apps/usp/plugins/terminal/height',self.RegenPlugin)
		self.client.notify_add('/apps/usp/plugins/terminal/width',self.RegenPlugin)
		self.client.notify_add('/apps/usp/plugins/terminal/background_color',self.RegenPlugin)
		self.client.notify_add('/apps/usp/plugins/terminal/foreground_color',self.RegenPlugin)
		self.client.notify_add('/apps/usp/plugins/terminal/back_picture',self.RegenPlugin)
		self.client.notify_add('/apps/usp/plugins/terminal/use_back_picture',self.RegenPlugin)
		self.client.notify_add('/apps/usp/plugins/terminal/sticky',self.RegenPlugin)
		self.client.notify_add('/apps/usp/plugins/terminal/icon',self.RegenPlugin)

		# First try to destroy any existing forked bash command.
		# Otherwise on reload plugin we get loads of bash sessions.
		os.chdir(os.path.expanduser("~"))
		try:
			os.kill(termPID, signal.SIGKILL)
			print "Terminated Terminal Process", termPID
		except:
			pass
		self.terminal = vte.Terminal()
		if FileExists(".uspbashrc") == True:
			fileis = os.path.expanduser("~")+"/.uspbashrc"
			print "Terminal Plugin is Using "+fileis+" Configuration File"
			termPID = self.terminal.fork_command("bash",["bash", "--rcfile", fileis] )
		else:
			termPID = self.terminal.fork_command("bash")
		self.terminal.connect("button-release-event", self.ButtonReleased )
		self.terminal.connect("key_press_event",self.keypressed)
		self.RegenPlugin()
		self.SetupEvents()
		#gobject.timeout_add(1000, self.DoTerm)

	def RebuildPlugin(self, *args, **kargs):
		self.GetGconfEntries()

	def RegenPlugin(self, *args, **kargs):
		self.GetGconfEntries()
		self.DoTerm()

	def SetupEvents(self):
		#Connect event handlers
		dic = {"on_window1_destroy" : self.thisquitfirst}
		self.wTree.signal_autoconnect(dic)

	def thisquitfirst(self, *args, **kargs):
		self.terminal.destroy()
		gtk.main_quit

	def GetGconfEntries(self):
		self.client = gconf.client_get_default()
		self.sticky = SetGconf( self.client, "bool", "/apps/usp/plugins/terminal/sticky", False )
		self.minimized = SetGconf( self.client, "bool", "/apps/usp/plugins/terminal/minimized", False )
		self.icon = SetGconf( self.client, "string", "/apps/usp/plugins/terminal/icon", "gnome-terminal" )
		self.termheight = SetGconf(self.client,'int','/apps/usp/plugins/terminal/height', 80)
		self.termwidth = SetGconf(self.client,'int','/apps/usp/plugins/terminal/width', 400)
		self.backcolor = SetGconf(self.client,'string','/apps/usp/plugins/terminal/background_color', "#FFFFFF").upper()
		self.forecolor = SetGconf(self.client,'string','/apps/usp/plugins/terminal/foreground_color', "#000000").upper()
		self.usepic = SetGconf(self.client,'bool','/apps/usp/plugins/terminal/use_back_picture', False)
		self.termpic = SetGconf(self.client,'string','/apps/usp/plugins/terminal/back_picture', '')
		self.saturate = SetGconf(self.client,'int','/apps/usp/plugins/terminal/background_saturation', 100)
		if self.saturate < 1:
			self.saturate=1
		if self.saturate > 100:
			self.saturate=100
		self.transparent = SetGconf(self.client,'bool','/apps/usp/plugins/terminal/transparent_background', False)
		self.use_composite = SetGconf(self.client,'bool','/apps/usp/plugins/terminal/use_composite', False)

	def SetHidden( self, state ):
		if state == True:
			WriteGconf( self.client, "bool", "/apps/usp/plugins/terminal/minimized", True )
		else:
			WriteGconf( self.client, "bool", "/apps/usp/plugins/terminal/minimized", False )

	def ButtonReleased( self, widget, ev ):
		if ev.button == 3:
			itemclicked = widget
			self.mTree = gtk.glade.XML( self.gladefile, "copypaste" )
			time = ev.time
			self.mTree.get_widget( "copyitem" ).connect( "activate", self.CopyStuff )
			self.mTree.get_widget( "pasteitem" ).connect( "activate", self.PasteStuff )
			self.mTree.get_widget( "copypaste" ).popup( None, None, None, ev.button, time )

	def CopyStuff(self, widget):
		self.terminal.copy_clipboard()
		return

	def PasteStuff(self, widget):
		self.terminal.paste_clipboard()
		return

	def keypressed(self, widget, ev):
		key_handled = False
		# Check state for Control, Shift and Mod2
		if  ev.state == gtk.gdk.SHIFT_MASK | gtk.gdk.CONTROL_MASK | gtk.gdk.MOD2_MASK:
			# Check if C key is pressed
			if ev.keyval == 67:
				# "<Ctrl><Shift>C"
				self.terminal.copy_clipboard()
				key_handled = True
			# Check if V key is pressed
			if ev.keyval == 86:
				# "<Ctrl><Shift>V"
				self.terminal.paste_clipboard()
				key_handled = True
		# If key_handled is False normal keypress handler takes control.
		return key_handled

	#Actually do something with the plugin
	def DoTerm(self):
		# Start of Inserted Terminal Code
		self.window = self.wTree.get_widget("window1")
		if self.window.get_screen().get_rgba_colormap() != None and self.window.get_screen().is_composited():
			self.window.set_colormap(self.window.get_screen().get_rgba_colormap()) 
			self.has_argb = True 
		else: 
			self.has_argb = False

		self.vbox1 = self.wTree.get_widget("vbox1")
		self.vbox1.set_size_request(self.termwidth,self.termheight)
		os.chdir(os.path.expanduser("~"))
		#termPID = self.terminal.fork_command("bash")
		if self.usepic==True:
			if os.path.isfile(self.termpic):
				self.terminal.set_background_image_file(self.termpic)
		self.terminal.set_background_saturation(float('%0.2f' % self.saturate)/100)
		white = gtk.gdk.color_parse('white')
		black = gtk.gdk.color_parse('black')
		self.terminal.set_colors(black, white, [])
		self.terminal.set_color_background(gtk.gdk.color_parse(self.backcolor))
		self.terminal.set_color_foreground(gtk.gdk.color_parse(self.forecolor))
		if self.has_argb and self.use_composite:
			self.terminal.set_background_transparent(False);
			self.terminal.set_opacity(int((self.saturate*65535)/100))
		else:
			self.terminal.set_background_transparent(self.transparent)
		self.terminal.show()
		self.vbox1.add(self.terminal)
		self.window.show_all()
		self.terminal.grab_focus()
		# End of Inserted Terminal Code

#---------------------------------------------------------------------------------------#
# USPconfig Section Below
#---------------------------------------------------------------------------------------#
# This is the Config Class it must be called "cfgpluginclass'
class cfgpluginclass:
	def __init__(self):
		# The Gladefile for the plugins USPconfig Tab
		self.gladefile = os.path.join(os.path.dirname(__file__), "terminal.glade")
		# Read GLADE file
		self.wTree = gtk.glade.XML(self.gladefile,"config")
		# Set 'window' property for the plugin (Must be the root widget)
		self.window = self.wTree.get_widget("config")
		# Set Heading, this will be used for the tab label in USPconfig
		self.heading = "Terminal"
		# Content Place Holder must be eventbox1
		self.content_holder = self.wTree.get_widget("eventbox2")
		# GConf Stuff - This just makes sure a gconf path is there.
		self.gconf_dir = '/apps/usp/plugins/terminal'
		self.client = gconf.client_get_default()
		self.client.add_dir('/apps/usp/plugins/terminal', gconf.CLIENT_PRELOAD_NONE)
		# Setup the Functions of the Glade files spin controls or entry boxes for Value Changes
		# Tip: For spinbutton controls use the "_value_changed" event not the "_changed" event.
		dic = { "on_window1_destroy" : gtk.main_quit,
				"on_TermWSpin_changed" : self.termw,
				"on_TermHSpin_changed" : self.termh,
				"on_TextColBtn_color_set": self.termfore,
				"on_BackColBtn_color_set": self.termback,
				"on_UsePicChkBtn_toggled" : self.usebackpic,
				"on_BackPicEntry_changed" : self.changepic,
				"on_SatSpin_changed" : self.termsat,
				"on_TransChkBtn_toggled" : self.termtrans,
				"on_CompChkBtn_toggled" : self.composite,
				"on_TermIconEntry_changed" : self.termiconchange,
				"on_StickyChkBtn_toggled" : self.termsticky}
		self.wTree.signal_autoconnect(dic)
		# Read Values from Gconf and Set Default Values if they don't exist.
		self.wTree.get_widget("TermWSpin").set_value(SetGconf(self.client,'int','/apps/usp/plugins/terminal/width',250))
		self.wTree.get_widget("TermHSpin").set_value(SetGconf(self.client,'int','/apps/usp/plugins/terminal/height',100))
		self.wTree.get_widget("TextColBtn").set_color(gtk.gdk.color_parse(SetGconf(self.client,'string','/apps/usp/plugins/terminal/foreground_color','#000000')))
		self.wTree.get_widget("BackColBtn").set_color(gtk.gdk.color_parse(SetGconf(self.client,'string','/apps/usp/plugins/terminal/background_color','#ffffff')))
		self.wTree.get_widget("UsePicChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/terminal/use_back_picture',False))
		self.wTree.get_widget("BackPicEntry").set_text(SetGconf(self.client,'string','/apps/usp/plugins/terminal/back_picture',''))
		self.wTree.get_widget("SatSpin").set_value(SetGconf(self.client,'int','/apps/usp/plugins/terminal/background_saturation',100))
		self.wTree.get_widget("TransChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/terminal/transparent_background',False))
		self.wTree.get_widget("CompChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/terminal/use_composite', False))
		self.wTree.get_widget("TermIconEntry").set_text(SetGconf(self.client,'string','/apps/usp/plugins/terminal/icon','gnome-terminal'))
		self.wTree.get_widget("StickyChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/terminal/sticky',False))

	# Functions for Changing Values when items checked or altered Section
	def termw(self, widget, **kargs):
	        self.client.set_int('/apps/usp/plugins/terminal/width',int(self.wTree.get_widget("TermWSpin").get_value()))

	def termh(self, widget, **kargs):
	        self.client.set_int('/apps/usp/plugins/terminal/height',int(self.wTree.get_widget("TermHSpin").get_value()))

	def termfore(self, widget, **kargs):
		tfcol=self.wTree.get_widget("TextColBtn").get_color()
		fcol_string='#' + (hex(tfcol.red)+'0')[2:4]+(hex(tfcol.green)+'0')[2:4]+(hex(tfcol.blue)+'0')[2:4]
		self.client.set_string('/apps/usp/plugins/terminal/foreground_color',fcol_string)

	def termback(self, widget, **kargs):
		tbcol=self.wTree.get_widget("BackColBtn").get_color()
		bcol_string='#' + (hex(tbcol.red)+'0')[2:4]+(hex(tbcol.green)+'0')[2:4]+(hex(tbcol.blue)+'0')[2:4]
		self.client.set_string('/apps/usp/plugins/terminal/background_color',bcol_string)

	def usebackpic(self, widget, **kargs):
		if self.wTree.get_widget("UsePicChkBtn").get_active() == True:
			self.client.set_bool('/apps/usp/plugins/terminal/use_back_picture',True)
			self.client.set_bool('/apps/usp/plugins/terminal/transparent_background',False)
			self.wTree.get_widget("TransChkBtn").set_active(False)
		else:
			self.client.set_bool('/apps/usp/plugins/terminal/use_back_picture',False)

	def changepic(self, widget, **kargs):
	        self.client.set_string('/apps/usp/plugins/terminal/back_picture',self.wTree.get_widget("BackPicEntry").get_text())
	def termsat(self, widget, **kargs):
	        self.client.set_int('/apps/usp/plugins/terminal/background_saturation',int(self.wTree.get_widget("SatSpin").get_value()))

	def termtrans(self, widget, **kargs):
		if self.wTree.get_widget("TransChkBtn").get_active() == True:
			self.client.set_bool('/apps/usp/plugins/terminal/transparent_background',True)
			self.client.set_bool('/apps/usp/plugins/terminal/use_back_picture',False)
			self.wTree.get_widget("UsePicChkBtn").set_active(False)
		else:
			self.client.set_bool('/apps/usp/plugins/terminal/transparent_background',False)

	def composite(self, widget, **kargs):
		if self.wTree.get_widget("CompChkBtn").get_active() == True:
			self.client.set_bool('/apps/usp/plugins/terminal/use_composite',True)
		else:
			self.client.set_bool('/apps/usp/plugins/terminal/use_composite',False)

	def termiconchange(self, widget, **kargs): 
		self.icon=self.wTree.get_widget("TermIconEntry").get_text()
		self.client.set_string('/apps/usp/plugins/terminal/icon',self.wTree.get_widget('TermIconEntry').get_text())

	def termsticky(self, widget, **kargs):
		if self.wTree.get_widget("StickyChkBtn").get_active() == True:
			self.client.set_bool('/apps/usp/plugins/terminal/sticky',True)
		else:
			self.client.set_bool('/apps/usp/plugins/terminal/sticky',False)
